237 lines
6.7 KiB
237 lines
6.7 KiB
#pragma once
|
|
#include "types.h"
|
|
|
|
#define SELF_REF_PML4_IDX 510
|
|
#define MAPPING_PML4_IDX 100
|
|
|
|
#define MAPPING_ADDRESS_BASE 0x0000327FFFE00000
|
|
#define SELF_REF_PML4 0xFFFFFF7FBFDFE000
|
|
|
|
#define EPT_LARGE_PDPTE_OFFSET(_) (((u64)(_)) & ((0x1000 * 0x200 * 0x200) - 1))
|
|
#define EPT_LARGE_PDE_OFFSET(_) (((u64)(_)) & ((0x1000 * 0x200) - 1))
|
|
|
|
#pragma section(".pdpt", read, write)
|
|
#pragma section(".pd", read, write)
|
|
#pragma section(".pt", read, write)
|
|
|
|
namespace mm
|
|
{
|
|
enum class map_type_t
|
|
{
|
|
map_src,
|
|
map_dest
|
|
};
|
|
|
|
typedef union _virt_addr_t
|
|
{
|
|
u64 value;
|
|
struct
|
|
{
|
|
u64 offset_4kb : 12;
|
|
u64 pt_index : 9;
|
|
u64 pd_index : 9;
|
|
u64 pdpt_index : 9;
|
|
u64 pml4_index : 9;
|
|
u64 reserved : 16;
|
|
};
|
|
|
|
struct
|
|
{
|
|
u64 offset_2mb : 21;
|
|
u64 pd_index : 9;
|
|
u64 pdpt_index : 9;
|
|
u64 pml4_index : 9;
|
|
u64 reserved : 16;
|
|
};
|
|
|
|
struct
|
|
{
|
|
u64 offset_1gb : 30;
|
|
u64 pdpt_index : 9;
|
|
u64 pml4_index : 9;
|
|
u64 reserved : 16;
|
|
};
|
|
|
|
} virt_addr_t, * pvirt_addr_t;
|
|
using phys_addr_t = virt_addr_t;
|
|
|
|
typedef union _pml4e
|
|
{
|
|
u64 value;
|
|
struct
|
|
{
|
|
u64 present : 1;
|
|
u64 writeable : 1;
|
|
u64 user_supervisor : 1;
|
|
u64 page_write_through : 1;
|
|
u64 page_cache : 1;
|
|
u64 accessed : 1;
|
|
u64 ignore_1 : 1;
|
|
u64 page_size : 1;
|
|
u64 ignore_2 : 4;
|
|
u64 pfn : 36;
|
|
u64 reserved : 4;
|
|
u64 ignore_3 : 11;
|
|
u64 nx : 1;
|
|
};
|
|
} pml4e, * ppml4e;
|
|
|
|
typedef union _pdpte
|
|
{
|
|
u64 value;
|
|
struct
|
|
{
|
|
u64 present : 1;
|
|
u64 rw : 1;
|
|
u64 user_supervisor : 1;
|
|
u64 page_write_through : 1;
|
|
u64 page_cache : 1;
|
|
u64 accessed : 1;
|
|
u64 ignore_1 : 1;
|
|
u64 large_page : 1;
|
|
u64 ignore_2 : 4;
|
|
u64 pfn : 36;
|
|
u64 reserved : 4;
|
|
u64 ignore_3 : 11;
|
|
u64 nx : 1;
|
|
};
|
|
} pdpte, * ppdpte;
|
|
|
|
typedef union _pde
|
|
{
|
|
u64 value;
|
|
struct
|
|
{
|
|
u64 present : 1;
|
|
u64 rw : 1;
|
|
u64 user_supervisor : 1;
|
|
u64 page_write_through : 1;
|
|
u64 page_cache : 1;
|
|
u64 accessed : 1;
|
|
u64 ignore_1 : 1;
|
|
u64 large_page : 1;
|
|
u64 ignore_2 : 4;
|
|
u64 pfn : 36;
|
|
u64 reserved : 4;
|
|
u64 ignore_3 : 11;
|
|
u64 nx : 1;
|
|
};
|
|
} pde, * ppde;
|
|
|
|
typedef union _pte
|
|
{
|
|
u64 value;
|
|
struct
|
|
{
|
|
u64 present : 1;
|
|
u64 rw : 1;
|
|
u64 user_supervisor : 1;
|
|
u64 page_write_through : 1;
|
|
u64 page_cache : 1;
|
|
u64 accessed : 1;
|
|
u64 dirty : 1;
|
|
u64 access_type : 1;
|
|
u64 global : 1;
|
|
u64 ignore_2 : 3;
|
|
u64 pfn : 36;
|
|
u64 reserved : 4;
|
|
u64 ignore_3 : 7;
|
|
u64 pk : 4;
|
|
u64 nx : 1;
|
|
};
|
|
} pte, * ppte;
|
|
|
|
typedef struct _npt_pml4e
|
|
{
|
|
union
|
|
{
|
|
u64 value;
|
|
struct
|
|
{
|
|
u64 present : 1;
|
|
u64 writeable : 1;
|
|
u64 user : 1;
|
|
u64 write_through : 1;
|
|
u64 cache_disable : 1;
|
|
u64 accessed : 1;
|
|
u64 reserved1 : 3;
|
|
u64 avl : 3;
|
|
u64 pfn : 40;
|
|
u64 reserved2 : 11;
|
|
u64 nx : 1;
|
|
};
|
|
};
|
|
} npt_pml4e, *pnpt_pml4e, npt_pdpte,
|
|
*pnpt_pdpte, npt_pde, *pnpt_pde;
|
|
|
|
typedef struct _npt_pte
|
|
{
|
|
union
|
|
{
|
|
u64 value;
|
|
struct
|
|
{
|
|
u64 present : 1;
|
|
u64 writeable : 1;
|
|
u64 user : 1;
|
|
u64 write_through : 1;
|
|
u64 cache_disable : 1;
|
|
u64 accessed : 1;
|
|
u64 dirty : 1;
|
|
u64 pat : 1;
|
|
u64 global : 1;
|
|
u64 avl : 3;
|
|
u64 pfn : 40;
|
|
u64 reserved : 11;
|
|
u64 nx : 1;
|
|
};
|
|
};
|
|
} npt_pte, *pnpt_pte;
|
|
|
|
typedef struct _npt_pde_2mb
|
|
{
|
|
union
|
|
{
|
|
u64 value;
|
|
struct
|
|
{
|
|
u64 present : 1;
|
|
u64 writeable : 1;
|
|
u64 user : 1;
|
|
u64 write_through : 1;
|
|
u64 cache_disable : 1;
|
|
u64 accessed : 1;
|
|
u64 dirty : 1;
|
|
u64 large_page : 1;
|
|
u64 global : 1;
|
|
u64 avl : 3;
|
|
u64 pat : 1;
|
|
u64 reserved1 : 8;
|
|
u64 pfn : 31;
|
|
u64 reserved2 : 11;
|
|
u64 nx : 1;
|
|
};
|
|
};
|
|
} npt_pde_2mb, * pnpt_pde_2mb;
|
|
|
|
__declspec(allocate(".pdpt")) inline pdpte pdpt[512];
|
|
__declspec(allocate(".pd")) inline pde pd[512];
|
|
__declspec(allocate(".pt")) inline pte pt[512];
|
|
|
|
inline const ppml4e hyperv_pml4{ reinterpret_cast<ppml4e>(SELF_REF_PML4) };
|
|
|
|
auto init() -> svm::vmxroot_error_t;
|
|
auto map_guest_phys(guest_phys_t phys_addr, map_type_t map_type = map_type_t::map_src) -> u64;
|
|
auto map_guest_virt(guest_phys_t dirbase, guest_virt_t virt_addr, map_type_t map_type = map_type_t::map_src) -> u64;
|
|
|
|
auto map_page(host_phys_t phys_addr, map_type_t map_type = map_type_t::map_src) -> u64;
|
|
auto get_map_virt(u16 offset = 0u, map_type_t map_type = map_type_t::map_src) -> u64;
|
|
|
|
auto translate(host_virt_t host_virt) -> u64;
|
|
auto translate_guest_physical(guest_phys_t guest_phys, map_type_t map_type = map_type_t::map_src) -> u64;
|
|
auto translate_guest_virtual(guest_phys_t dirbase, guest_virt_t guest_virt, map_type_t map_type = map_type_t::map_src) -> u64;
|
|
|
|
auto read_guest_phys(guest_phys_t dirbase, guest_phys_t guest_phys, guest_virt_t guest_virt, u64 size) -> svm::vmxroot_error_t;
|
|
auto write_guest_phys(guest_phys_t dirbase, guest_phys_t guest_phys, guest_virt_t guest_virt, u64 size) -> svm::vmxroot_error_t;
|
|
auto copy_guest_virt(guest_phys_t dirbase_src, guest_virt_t virt_src, guest_virt_t dirbase_dest, guest_virt_t virt_dest, u64 size) ->svm::vmxroot_error_t;
|
|
} |